# -*- coding: utf-8 -*-
#   文件说明
# @Time    ： 2025/11/17  14:51
# @Auther  ： 徐良
# File     :  saveBill.py
from typing import List, Dict, Set, Optional, Union, Any, Tuple
from PySide6.QtCore import QDate, QDateTime
from baseClass.model.editableQueryModel import EditableSqlModel
from dbService.db_service import execute_sql_list_in_transaction
from PySide6.QtSql import QSqlRecord
from PySide6.QtCore import Qt


class BaseSqlClass:
    def __init__(self):
        super().__init__()

    @staticmethod
    def get_del_sql(table_name, fid_set) -> Optional[str]:
        """根据表名和fid集合，获取删除语句"""
        id_list = list(fid_set)
        sql = None
        if len(id_list) > 0:
            id_str_list = [str(x) for x in id_list]
            id_str = ','.join(id_str_list)
            sql = f"delete from {table_name} where fid in ({id_str});"
        return sql

    @staticmethod
    def get_rec_dict_list_for_no_id(model: EditableSqlModel) -> List[Dict[str, str]]:
        # 2. 获取所有行的字典列表（直接复用模型的 get_row_dicts 方法，高效且兼容）
        all_row_dicts = model.get_row_dicts()

        no_id_records = []

        for row_dict in all_row_dicts:
            fid_value = row_dict.get("fid")
            # 判断是否为 None 或 空字符串（严格匹配，如需包含纯空格可改为：if fid_value is None or str(fid_value).strip() == ""）
            if fid_value is None or fid_value == "":
                no_id_records.append(row_dict)

        return no_id_records

    @staticmethod
    def get_record_in_model(model: EditableSqlModel, fid: int) -> Optional[QSqlRecord]:
        """获取记录"""
        rec = None
        for row in range(0, model.rowCount()):
            if fid == model.record(row).value('FId'):
                rec = model.record(row)
                break
        return rec

    def get_value_list_by_record(self, record: QSqlRecord,
                                 field_list: List[str],
                                 type_list: List[str]) -> List[str]:
        v_list = []
        for field, type_str in zip(field_list, type_list):
            v = self.object_to_str(record.value(field))
            # 根据类型决定是否要加引号
            v_quotation = self.get_quotation(v, type_str)
            v_list.append(v_quotation)

        return v_list


    @staticmethod
    def get_update_expression(f_list: List[str],
                              v_list: List[str],
                              j_list: List[int]) -> str:

        exp_list = []
        for field, value_str, join_int in zip(f_list, v_list, j_list):
            if join_int:
                exp = f"{field}={value_str}"
                exp_list.append(exp)

        return ','.join(exp_list)

    def get_update_sql(self, model: EditableSqlModel,
                       table_name: str,
                       field_list: List[str],
                       type_list: List[str],
                       join_list: List[int],
                       update_set: Set[int]) -> List[str]:
        """"""
        sql_list = []
        update_list = list(update_set)

        for fid in update_list:
            rec = self.get_record_in_model(model=model, fid=fid)
            if rec is not None:
                value_list = self.get_value_list_by_record(record=rec,
                                                           field_list=field_list,
                                                           type_list=type_list)
                u_exp = self.get_update_expression(f_list=field_list,
                                                   v_list=value_list,
                                                   j_list=join_list)
                sql = f"update {table_name} set {u_exp} where fid={fid};"
                sql_list.append(sql)


        return sql_list

    def get_value_list_by_dict(self, rec_dict: Dict[str, Any],
                               field_list: List[str],
                               type_list: List[str]) -> List[str]:

        v_list = []
        for field, type_str in zip(field_list, type_list):
            v = self.object_to_str(rec_dict.get(field.lower()))
            # 根据类型决定是否要加引号
            v_quotation = self.get_quotation(v, type_str)
            v_list.append(v_quotation)
        return v_list

    @staticmethod
    def get_insert_str(field_list: List[str],
                       value_list: List[str],
                       join_list: List[int]) -> Tuple[str, str]:
        f_list = []
        v_list = []
        for field, value, join in zip(field_list, value_list, join_list):
            if join:
                f_list.append(field)
                v_list.append(value)

        return ','.join(f_list), ','.join(v_list)

    def get_insert_sql(self, model: EditableSqlModel,
                       table_name: str,
                       field_list: List[str],
                       type_list: List[str],
                       join_list: List[int]) -> List[str]:

        dict_list = self.get_rec_dict_list_for_no_id(model)

        sql_list = []
        for rec_dict in dict_list:
            v_list = self.get_value_list_by_dict(rec_dict, field_list, type_list)
            field_str, value_str = self.get_insert_str(field_list=field_list,
                                              value_list=v_list,
                                              join_list=join_list)

            sql = f"insert into {table_name} ({field_str}) values ({value_str});"
            sql_list.append(sql)

        return sql_list

    @staticmethod
    def object_to_str(obj: Optional[Union[int, float, str, QDate, QDateTime]]) -> str:
        """
        将对象转换为符合业务需求的字符串格式。
            转换规则：
              - 整数和浮点数转换为对应字符串形式
              - None值转换为空字符串 ''
              - QDate类型格式化为 'YYYY-MM-DD' 格式
              - QDateTime类型转换为ISO 8601标准格式
              - 其他类型调用默认str()转换

            参数：
                obj: 待转换对象，支持None/数字/字符串/QDate/QDateTime类型

            返回：
                str: 根据转换规则处理后的字符串结果

            示例：
                object_to_str(113)          # 整数转换
                '113'
                object_to_str(None)        # None处理
                ''
                object_to_str(QDate(2021, 10, 1))  # 日期格式化
                '2021-10-01'
        """

        # 处理空值情况
        if obj is None:
            return ''

        # 处理数值类型
        if isinstance(obj, (int, float)):
            return str(obj)

        # 处理Qt日期类型
        if isinstance(obj, QDate):
            ret = str(obj.toString('yyyy-MM-dd'))
            return ret if ret else '2000-01-01'

        # 处理Qt日期时间类型
        if isinstance(obj, QDateTime):
            ret = str(obj.toString(Qt.DateFormat.ISODate))
            return ret if ret else '2000-01-01 00:00'

        # 默认字符串转换
        return str(obj)

    @staticmethod
    def get_quotation(value: str, type_str: str) -> str:
        """决定是否加引号"""
        if type_str.lower() == 'integer':
            if value in ['', None]:
                return '0'
            else:
                return value

        elif type_str.lower() == 'float':
            if value in ['', None]:
                return '0.0'
            else:
                return value

        elif type_str.lower() == 'string':
            return f"'{value}'"

        elif type_str.lower() == 'date':
            if value in ['', None]:
                return "'2000-01-01'"
            else:
                return f"'{value}'"

        elif type_str.lower() == 'datetime':
            if value in ['', None]:
                return "'2000-01-01 00-00'"
            else:
                return f"'{value}'"

        elif type_str.lower() == 'time':
            if value in ['', None]:
                return "'00-00'"
            else:
                return f"'{value}'"

        else:
            return value

    @staticmethod
    def exe_sql(sqls: List[str]) -> Tuple[bool, str]:

       return execute_sql_list_in_transaction(sqls)

class SaveTableAction(BaseSqlClass):
    """
    保存独立的一张表
    """
    def __init__(self):
        super().__init__()

    def save_table(self, model: EditableSqlModel,
                   table_name: str,
                   field_list: List[str],
                   type_list: List[str],
                   join_list: List[int],
                   update_set: Set,
                   del_set: Set
                   ) -> Tuple[bool, str]:
        sql_list = []
        # 获取del语句
        sql = self.get_del_sql(table_name, del_set)
        if sql is not None:
            sql_list.append(sql)

        # 获取update语句
        sqls = self.get_update_sql(model=model,
                                   table_name=table_name,
                                   field_list=field_list,
                                   type_list=type_list,
                                   join_list=join_list,
                                   update_set=update_set)
        sql_list.extend(sqls)

        # 获取insert语句
        sqls = self.get_insert_sql(model=model,
                                   table_name=table_name,
                                   field_list=field_list,
                                   type_list=type_list,
                                   join_list=join_list)

        sql_list.extend(sqls)
        return self.exe_sql(sql_list)


class SavePCTableAction(BaseSqlClass):
    """
    同时保存父子表
    """
    def __init__(self):
        super().__init__()

    def _get_master_sql(self, m_model: EditableSqlModel,
                  m_table_name: str,
                  m_field_list: List[str],
                  m_type_list: List[str],
                  m_join_list: List[int],
                  m_update_set: Set[int],
                  m_del_set: Set[int]) -> List[str]:
        """处理主表，得到sql列表"""
        sql_list = []
        # 获取del语句
        sql = self.get_del_sql(m_table_name, m_del_set)
        if sql is not None:
            sql_list.append(sql)

        # 获取update语句
        sqls = self.get_update_sql(model=m_model,
                                   table_name=m_table_name,
                                   field_list=m_field_list,
                                   type_list=m_type_list,
                                   join_list=m_join_list,
                                   update_set=m_update_set)
        sql_list.extend(sqls)

        # 获取insert语句
        sqls = self.get_insert_sql(model=m_model,
                                   table_name=m_table_name,
                                   field_list=m_field_list,
                                   type_list=m_type_list,
                                   join_list=m_join_list)

        sql_list.extend(sqls)

        return sql_list


    def _get_child_sql(self, c_model: EditableSqlModel,
                  c_table_name: str,
                  c_field_list: List[str],
                  c_type_list: List[str],
                  c_join_list: List[int],
                  c_update_set: Set[int],
                  c_del_set: Set[int]) -> List[str]:
        """处理子表, 得到sql列表"""
        sql_list = []
        # 获取del语句
        sql = self.get_del_sql(c_table_name, c_del_set)
        if sql is not None:
            sql_list.append(sql)

        # 获取update语句
        sqls = self.get_update_sql(model=c_model,
                                   table_name=c_table_name,
                                   field_list=c_field_list,
                                   type_list=c_type_list,
                                   join_list=c_join_list,
                                   update_set=c_update_set)
        sql_list.extend(sqls)

        # 获取insert语句
        sqls = self.get_insert_sql(model=c_model,
                                   table_name=c_table_name,
                                   field_list=c_field_list,
                                   type_list=c_type_list,
                                   join_list=c_join_list)

        sql_list.extend(sqls)

        return sql_list

    def save_data(self, m_model: EditableSqlModel,
                  m_table_name: str,
                  m_field_list: List[str],
                  m_type_list: List[str],
                  m_join_list: List[int],
                  m_update_set: Set[int],
                  m_del_set: Set[int],
                  c_model: EditableSqlModel,
                  c_table_name: str,
                  c_field_list: List[str],
                  c_type_list: List[str],
                  c_join_list: List[int],
                  c_update_set: Set[int],
                  c_del_set: Set[int]
                  ) -> Tuple[bool, str]:
        """"""
        sql_list = []
        # 处理主表
        sqls = self._get_master_sql(m_model=m_model,
                                    m_table_name=m_table_name,
                                    m_field_list=m_field_list,
                                    m_type_list=m_type_list,
                                    m_join_list=m_join_list,
                                    m_update_set=m_update_set,
                                    m_del_set=m_del_set)
        sql_list.extend(sqls)

        # 处理子表
        sqls = self._get_child_sql(c_model=c_model,
                                   c_table_name=c_table_name,
                                   c_field_list=c_field_list,
                                   c_type_list=c_type_list,
                                   c_join_list=c_join_list,
                                   c_update_set=c_update_set,
                                   c_del_set=c_del_set)
        sql_list.extend(sqls)
        print(sql_list)
        return self.exe_sql(sql_list)



class SaveMHBAction:
    """
    同时保存三张表，主表、表头表、表体表
    """
    def __init__(self):
        super().__init__()


class SaveBillAction:
    """
    保存单据表，需要获取单据号
    """
    def __init__(self):
        super().__init__()